package com.wxmit.framework.excel.util;

import cn.hutool.core.collection.ListUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.builder.AbstractExcelReaderParameterBuilder;
import com.alibaba.excel.read.builder.ExcelReaderBuilder;
import com.alibaba.excel.read.builder.ExcelReaderSheetBuilder;
import com.alibaba.excel.read.metadata.ReadWorkbook;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.wxmit.base.exception.excel.ExcelReadValidException;
import com.wxmit.framework.excel.domain.ExcelImportResult;
import com.wxmit.framework.excel.handler.ExcelExportTemplateHandler;
import com.wxmit.framework.excel.lintener.ExcelReadValidListener;
import lombok.extern.slf4j.Slf4j;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * 针对框架内的excel操作吨统一封装
 *
 * @author huangxiong
 * @version V1.0
 * @date 2023/1/5 15:28
 */
@Slf4j
public final class ExcelUtils {

    /**
     *  根据对象导出空模版
     * @param fileName 文件名
     * @param targetClass 对象
     */
    public static void exportEmptyTemplate(String fileName,Class<?> targetClass){
        ExcelWriterBuilder write = EasyExcel.write(fileName, targetClass);
        exportEmptyTemplate(write);
    }

    /**
     *  根据对象导出空模版
     * @param outputStream 导出流
     * @param targetClass 对象
     */
    public static void exportEmptyTemplate(OutputStream outputStream, Class<?> targetClass){
        ExcelWriterBuilder write = EasyExcel.write(outputStream, targetClass).autoCloseStream(true);
        exportEmptyTemplate(write);
    }

    /**
     *  根据对象导出空模版
     * @param builder ExcelWriterBuilder：上游设置好参数吨builder
     */
    public static void exportEmptyTemplate(ExcelWriterBuilder builder){
        builder.registerWriteHandler(new ExcelExportTemplateHandler())
                .sheet("模板")
                .doWrite(ListUtil.empty());
    }


    /**
     *   导入excel
     * @param inputStream 文件流
     * @param fastFail 是否快速失败：true：则失败后 不再导入余下数据；false：失败后，仍然导入余下数据。
     * @param targetClass 目标对象
     * @param <T> 目标对象范型
     * @return excel 导入 结果对象
     * @throws ExcelReadValidException excel 导入校验 异常
     */
    public static <T> ExcelImportResult<T> importByClass(InputStream inputStream, Boolean fastFail , Class<T> targetClass)throws ExcelReadValidException{
        ExcelReaderBuilder excelReaderBuilder = EasyExcel.read().file(inputStream).head(targetClass);
        return importByClass(excelReaderBuilder,fastFail);
    }

    public static <T> ExcelImportResult<T> importByClass(String fileName, Boolean fastFail , Class<T> targetClass)throws ExcelReadValidException{
        ExcelReaderBuilder excelReaderBuilder = EasyExcel.read().file(fileName).head(targetClass);
        return importByClass(excelReaderBuilder,fastFail);
    }

    public static  <T> ExcelImportResult<T> importByClass(AbstractExcelReaderParameterBuilder excelReaderBuilder, Boolean fastFail)throws ExcelReadValidException{
        List<T> list = new ArrayList<T>();
        ExcelImportResult<T> importResult = new ExcelImportResult<>();
        ExcelReaderSheetBuilder sheetBuilder = excelReaderBuilder instanceof ExcelReaderSheetBuilder ? ((ExcelReaderSheetBuilder)excelReaderBuilder).registerReadListener(new ExcelReadValidListener<>(fastFail, list)) : ((ExcelReaderBuilder)excelReaderBuilder).registerReadListener(new ExcelReadValidListener<>(fastFail, list)).sheet();
        try {
            sheetBuilder.doRead();
        }catch (ExcelReadValidException e){
            log.debug(e.toString());
            importResult.setException(e);
        }
        importResult.setResult(list);
        return importResult;
    }


}
